package com.github.panpf.sketch.sample.image

import android.app.Application
import android.widget.ImageView.ScaleType
import androidx.core.view.descendants
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.lifecycleScope
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.RecyclerView.Adapter
import com.github.panpf.sketch.sample.prefsService
import com.github.panpf.sketch.sample.util.lifecycleOwner
import com.github.panpf.sketch.sample.widget.MyRecyclerView
import com.github.panpf.sketch.util.SketchUtils
import com.github.panpf.zoomimage.SketchZoomImageView
import com.github.panpf.zoomimage.view.zoom.ScrollBarSpec
import com.github.panpf.zoomimage.zoom.ReadMode
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.launch

class SettingsEventViewModel(application: Application) : AndroidViewModel(application) {

    private val prefsService = application.prefsService

    val listRestartImageFlow: Flow<Any> = merge(
        prefsService.saveCellularTrafficInList.sharedFlow,

        prefsService.resizePrecision.sharedFlow,
        prefsService.resizeScale.sharedFlow,
        prefsService.longImageResizeScale.sharedFlow,
        prefsService.otherImageResizeScale.sharedFlow,

        prefsService.bitmapQuality.sharedFlow,
        prefsService.colorSpace.sharedFlow,
        prefsService.inPreferQualityOverSpeed.sharedFlow,

        prefsService.disabledMemoryCache.sharedFlow,
        prefsService.disabledResultCache.sharedFlow,
        prefsService.disabledDownloadCache.sharedFlow,
        prefsService.disallowReuseBitmap.sharedFlow,

        prefsService.disallowAnimatedImageInList.sharedFlow,
    )

    val listReloadFlow: SharedFlow<Any> = prefsService.ignoreExifOrientation.sharedFlow

    fun observeListSettings(recyclerView: MyRecyclerView) {
        recyclerView.lifecycleOwner.lifecycleScope.launch {
            listRestartImageFlow.collect {
                recyclerView.descendants.forEach {
                    SketchUtils.restart(it)
                }
            }
        }

        recyclerView.lifecycleOwner.lifecycleScope.launch {
            listReloadFlow.collect {
                recyclerView.adapter?.findPagingAdapter()?.refresh()
            }
        }
    }

    fun observeZoomSettings(zoomImageView: SketchZoomImageView) {
        zoomImageView.lifecycleOwner.lifecycleScope.launch {
            prefsService.scrollBarEnabled.stateFlow.collect {
                zoomImageView.scrollBar = if (it) ScrollBarSpec.Default else null
            }
        }
        zoomImageView.lifecycleOwner.lifecycleScope.launch {
            prefsService.readModeEnabled.stateFlow.collect {
                zoomImageView.zoomable.readModeState.value = if (it) ReadMode.Default else null
            }
        }
        zoomImageView.lifecycleOwner.lifecycleScope.launch {
            prefsService.showTileBounds.stateFlow.collect {
                zoomImageView.subsampling.showTileBoundsState.value = it
            }
        }
        zoomImageView.lifecycleOwner.lifecycleScope.launch {
            prefsService.scaleType.stateFlow.collect {
                zoomImageView.scaleType = ScaleType.valueOf(it)
            }
        }
    }

    private fun Adapter<*>.findPagingAdapter(): PagingDataAdapter<*, *>? {
        when (this) {
            is PagingDataAdapter<*, *> -> {
                return this
            }

            is ConcatAdapter -> {
                this.adapters.forEach {
                    it.findPagingAdapter()?.let { pagingDataAdapter ->
                        return pagingDataAdapter
                    }
                }
                return null
            }

            else -> {
                return null
            }
        }
    }
}